// Copyright (c) 2014-present, b3log.org
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package i18n includes internationalization related manipulations.
package i18n

import (
	"encoding/json"
	"io/ioutil"
	"os"
	"sort"
	"strings"

	"chainmaker.org/chainmaker/smarteditor/logger"
)

//I18nResourcePath internationalization resource path
const ResourcePath = "./data/i18n"

var log = logger.Get()

type localeConf struct {
	Name     string
	LangMap  map[string]interface{}
	TimeZone string
}

var localeNameList = make([]string, 0)

var localeMap = map[string]localeConf{}

// Load loads i18n message configurations.
func Load() {
	if len(localeMap) != 0 {
		log.Debugf("[i18n load], load i18n file. file has load.")
		return
	}

	f, _ := os.Open(ResourcePath)
	fileNames, _ := f.Readdirnames(-1)
	log.Infof("[i18n load], load i18n file. files:%s", fileNames)
	if err := f.Close(); err != nil {
		log.Warnf("[i18n load] close file failed. file:%s", f.Name())
	}
	for _, fileName := range fileNames {
		if !strings.HasSuffix(fileName, ".json") {
			continue
		}
		localFileName := fileName[:strings.LastIndex(fileName, ".")]
		localeNameList = append(localeNameList, localFileName)
		loadLocalFile(fileName, localFileName)
	}
	sort.Strings(localeNameList)
	log.Infof("[i18n load], load i18n file, load success. local file name list:%s, data:%v", localeNameList, localeMap)
}

func loadLocalFile(fileName string, localFileName string) {
	bytes, err := ioutil.ReadFile(ResourcePath + "/" + fileName)
	if nil != err {
		log.Error("[i18n load] loadLocalFile failed. file name:%s, err:%s", fileName, err.Error())
		os.Exit(-1)
	}

	l := localeConf{Name: localFileName}
	err = json.Unmarshal(bytes, &l.LangMap)
	if nil != err {
		log.Error("[i18n load] loadLocalFile unmarshal failed. err:%s", err.Error())
		os.Exit(-1)
	}
	localeMap[localFileName] = l
}

// Get gets a message with the specified locale conf
func Get(locale, key string) interface{} {
	if len(locale) == 0 {
		locale = "zh_CN"
	}
	return localeMap[locale].LangMap[key]
}

// GetAll gets all messages with the specified locale's Conf
func GetAll(locale string) map[string]interface{} {
	if len(locale) == 0 {
		locale = "zh_CN"
	}
	return localeMap[locale].LangMap
}

// GetLocalesNames gets names of all locales. Returns ["zh_CN", "en_US"] for example
func GetLocalesNames() []string {
	return localeNameList
}
